package ws.performancetest.tests.synchronization.lock;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Implementation of the shared memory using {@link ReentrantReadWriteLock}.
 *
 * @author Wilson Santos, 36228 <wilson.santos@ua.pt>
 */
public class RWLockImpl extends AbstractSharedListImpl {

  private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  private final Lock wlock = lock.writeLock();
  private final Lock rlock = lock.readLock();

  public void add() throws InterruptedException {
    assert invariant();

    /* If there's no space, wait. */
    while (true) {
      wlock.lock();
      if (list < MAX_SIZE) {
        break;
      } else {
        wlock.unlock();
      }
    }
    /* Add one element. */
    this.list++;
    wlock.unlock();

    assert invariant();
  }

  public void remove() {
    assert invariant();

    /* If there's no elements, wait. */
    while (true) {
      wlock.lock();
      if (list > 0) {
        break;
      } else {
        wlock.unlock();
      }
    }
    /* Remove one element. */
    this.list--;
    wlock.unlock();

    assert invariant();
  }

  public void read() throws InterruptedException {
    rlock.lock();
    try {
    } finally {
      rlock.unlock();
    }
  }

  public void write() throws InterruptedException {
    wlock.lock();
    try {
    } finally {
      wlock.unlock();
    }
  }
}
